import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutterapp2/base/request/common_request_state_callback.dart';
import 'package:flutterapp2/model/base_response.dart';

import 'request.dart';

class BaseRequestPage<T> extends StatefulWidget {
  const BaseRequestPage({
    Key key,
    @required this.request,
    @required this.builder,
    this.requestStateCallback = const CommonRequestStateCallback(),
    this.resultChecker,
  })  : assert(builder != null),
        assert(requestStateCallback != null),
        super(key: key);

  final RequestBuilder<T> request;
  final ContentWidgetBuilder<T> builder;
  final RequestStateCallback requestStateCallback;
  final ResultChecker<T> resultChecker;

  @override
  _BaseRequestPageState<T> createState() => _BaseRequestPageState();
}

class _BaseRequestPageState<T> extends State<BaseRequestPage<T>> {
  StreamController _streamController;
  StreamController _contentController;
  T _result;

  @override
  void initState() {
    super.initState();
    _streamController = StreamController();
    _contentController = StreamController();
    // initState方法中使用context
//    Future.delayed(Duration.zero, doRequest);
    doRequest();
  }

  @override
  void dispose() {
    _streamController.close();
    _contentController.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      alignment: Alignment.topLeft,
      children: <Widget>[
        // content
        StreamBuilder(
          initialData: RequestState.Empty,
          builder: _buildContent,
          stream: _contentController.stream,
        ),
        Center(
          child: StreamBuilder(
            initialData: RequestState.Loading,
            builder: _buildWidget,
            stream: _streamController.stream,
          ),
        )
      ],
    );
  }

  Widget _buildContent(BuildContext context, AsyncSnapshot snapshot) {
    if (snapshot.data == RequestState.Success) {
      return widget.builder(context, _result, doRequest);
    }

    return const SizedBox.shrink();
  }

  /// 根据各种状态构建状态的widget
  Widget _buildWidget(BuildContext context, AsyncSnapshot snapshot) {
    if (snapshot.hasError) {
      return widget.requestStateCallback
          .errorWidget(context, doRequest, snapshot.error);
    }

    if (snapshot.data == RequestState.Loading) {
      return widget.requestStateCallback.loadingWidget(context);
    }

    if (snapshot.data == RequestState.Empty) {
      return widget.requestStateCallback.emptyWidget(context, doRequest);
    }
    return const SizedBox.shrink();
  }

  /// 发起请求
  doRequest() {
    _streamController.add(RequestState.Loading);
//    _contentController.add(RequestState.Loading);
    widget.request().then((data) {
      _result = data;
      if (data == null) {
        //具体业务可以判断BaseResponse
        _streamController.addError(data);
        _contentController.addError(data);
        return;
      }

      if (_isValid(data)) {
        _streamController.add(RequestState.Success);
        _contentController.add(RequestState.Success);
      } else {
        _streamController.add(RequestState.Empty);
        _contentController.add(RequestState.Empty);
      }
    }, onError: (onError) {
      _streamController.addError(onError);
      _contentController.addError(onError);
    });
  }

  bool _isValid(T data) {
    if (widget.resultChecker != null) {
      return widget.resultChecker(data);
    } else {
      return data != null && data is BaseResponse && data.hasData();
    }
  }
}
